import {
  _decorator,
  Component,
  Node,
  Vec3,
  Label,
  BlockInputEvents,
  Prefab,
  instantiate,
  find,
} from "cc";
import { Cell } from "./Cell";
import { CellGroupConfig, CellType } from "./Types";
import { LEVEL_DATA } from "./LevelData";
import { CellGroup } from "./CellGroup";
import { cellGroups } from "./CellGroupData";
import { CellGroupContainer } from "./CellGroupContainer";
import { GridContainer } from "./GridContainer";
const { ccclass, property } = _decorator;

@ccclass("GameManager")
export class GameManager extends Component {
  public static instance: GameManager = null;

  @property(Node)
  roadContainer: Node = null;

  @property
  currentLevel: number = 0;

  @property(Label)
  currLevelLabel: Label = null;

  @property(Prefab)
  successPanel: Prefab = null;

  @property(Prefab)
  homePanel: Prefab = null;

  @property(Prefab)
  selectLevelPanel: Prefab = null;

  @property(CellGroupContainer)
  cellGroupContainer: CellGroupContainer = null;

  @property(GridContainer)
  gridContainer: GridContainer = null;

  private successPanelInstance: Node = null;
  private homePanelInstance: Node = null;
  private selectLevelPanelInstance: Node = null;
  private static readonly LAST_LEVEL_KEY = 'lastPlayedLevel';

  onLoad() {
    GameManager.instance = this;
    this.showHomePanel();
    this.restartLevel();
  }

  onDestroy() {}

  initGrid() {
    this.currLevelLabel.string = `Level ${this.currentLevel + 1}`;
    this.gridContainer.initGrid(this.currentLevel);
  }

  update(deltaTime: number) {}

  // 切换到下一关
  loadNextLevel() {
    this.hideSuccessPanel();
    this.currentLevel++;
    if (this.currentLevel >= LEVEL_DATA.length) {
      this.currentLevel = 0;
    }
    this.saveLastLevel();
    
    this.clearGrid();
    this.cellGroupContainer.reinitialize();
    this.initGrid();
  }

  restartLevel() {
    this.cellGroupContainer.setPickedCellGroup(null);
    this.clearGrid();
    this.cellGroupContainer.reinitialize();
    this.initGrid();
  }

  // 清理当前网格
  private clearGrid() {
    this.gridContainer.clearGrid();
  }

  // 世界坐标转网格坐标
  worldToGrid(worldPos: Vec3): { x: number; y: number } {
    return this.gridContainer.worldToGrid(worldPos);
  }

  // 尝试放置 CellGroup
  tryPlaceCellGroup(cellGroup: CellGroup): boolean {
    const gridPos = cellGroup.getGridPosition();

    if (!this.isValidGridPosition(gridPos.x, gridPos.y)) {
      return false;
    }

    const result = this.canPlaceCellGroup(gridPos.x, gridPos.y, cellGroup);

    if (result.success && result.position) {
      this.placeCellGroup(result.position.x, result.position.y, cellGroup);
      return true;
    }

    return false;
  }

  private isValidGridPosition(x: number, y: number): boolean {
    return this.gridContainer.isValidGridPosition(x, y);
  }

  // 添加一个新的辅助方法来计算重叠度
  private calculateOverlap(
    cellPos: Vec3,
    gridX: number,
    gridY: number
  ): number {
    const gridWorldPos = this.gridToWorld(gridX, gridY);
    const distance = Vec3.distance(cellPos, gridWorldPos);
    const overlap = Math.max(0, 1 - distance / this.gridContainer.CELL_SIZE);
    return overlap;
  }

  // 修改 canPlaceCellGroup 方法
  private canPlaceCellGroup(
    x: number,
    y: number,
    cellGroup: CellGroup
  ): {
    success: boolean;
    position?: { x: number; y: number; isHorizontal: boolean };
  } {
    const isHorizontal = cellGroup.node.angle % 180 !== 0;

    const cellPositions = cellGroup.node.children.map((child) => {
      const pos = child.getWorldPosition();
      pos.x -= this.gridContainer.CELL_SIZE / 2; // 使用gridContainer的CELL_SIZE
      pos.y -= this.gridContainer.CELL_SIZE / 2;
      return pos;
    });

    const gridPositions: Array<{ x: number; y: number }> = [];
    for (let dy = -1; dy <= 1; dy++) {
      for (let dx = -1; dx <= 1; dx++) {
        gridPositions.push({
          x: Math.floor(x + dx),
          y: Math.floor(y + dy),
        });
      }
    }

    let bestPositions: Array<{ x: number; y: number; overlap: number }> = [];
    gridPositions.forEach((pos) => {
      if (
        !this.isValidGridPosition(pos.x, pos.y) ||
        this.gridContainer.getCellType(pos.x, pos.y) !== CellType.Empty
      ) {
        return;
      }

      const overlaps = cellPositions.map((cellPos) =>
        this.calculateOverlap(cellPos, pos.x, pos.y)
      );
      const avgOverlap =
        overlaps.reduce((sum, val) => sum + val, 0) / overlaps.length;

      bestPositions.push({ ...pos, overlap: avgOverlap });
    });

    bestPositions.sort((a, b) => b.overlap - a.overlap);

    if (bestPositions.length < 2) {
      return { success: false };
    }

    const [pos1, pos2] = bestPositions;
    if (pos1.overlap < 0.3) {
      return { success: false };
    }

    const isAdjacent = isHorizontal
      ? pos1.y === pos2.y && Math.abs(pos1.x - pos2.x) === 1
      : pos1.x === pos2.x && Math.abs(pos1.y - pos2.y) === 1;

    if (isAdjacent) {
      let startPos;
      if (isHorizontal) {
        startPos = pos1.x <= pos2.x ? pos1 : pos2;
      } else {
        startPos = pos1.y <= pos2.y ? pos1 : pos2;
      }

      const worldPos = this.gridToWorld(startPos.x, startPos.y);
      cellGroup.node.setWorldPosition(worldPos);

      return {
        success: true,
        position: {
          x: startPos.x,
          y: startPos.y,
          isHorizontal,
        },
      };
    }

    return { success: false };
  }

  private placeCellGroup(x: number, y: number, cellGroup: CellGroup) {
    const cellComponents = cellGroup.node.getComponentsInChildren(Cell);
    if (cellComponents.length !== 2) {
      return;
    }

    const isHorizontal = cellGroup.node.angle % 180 !== 0;
    const rotationSteps = Math.floor(cellGroup.node.angle / 90);

    const rotateExits = (exits: boolean[]): boolean[] => {
      const newExits = [...exits];
      for (let i = 0; i < rotationSteps; i++) {
        const temp = [...newExits];
        newExits[0] = temp[1];
        newExits[1] = temp[2];
        newExits[2] = temp[3];
        newExits[3] = temp[0];
      }
      return newExits;
    };

    if (isHorizontal) {
      const [cell1, cell2] = cellComponents;
      const exits1 = rotateExits(cell1.getExits());
      const exits2 = rotateExits(cell2.getExits());
      if (cellGroup.node.angle % 360 === 270) {
        this.gridContainer.setCellTypeAndExits(x, y, cell2.getType(), exits2);
        this.gridContainer.setCellTypeAndExits(
          x + 1,
          y,
          cell1.getType(),
          exits1
        );
      } else {
        this.gridContainer.setCellTypeAndExits(x, y, cell1.getType(), exits1);
        this.gridContainer.setCellTypeAndExits(
          x + 1,
          y,
          cell2.getType(),
          exits2
        );
      }
    } else {
      const [cell1, cell2] = cellComponents;
      const exits1 = rotateExits(cell1.getExits());
      const exits2 = rotateExits(cell2.getExits());
      if (cellGroup.node.angle % 360 === 180) {
        this.gridContainer.setCellTypeAndExits(x, y, cell1.getType(), exits1);
        this.gridContainer.setCellTypeAndExits(
          x,
          y + 1,
          cell2.getType(),
          exits2
        );
      } else {
        this.gridContainer.setCellTypeAndExits(x, y, cell2.getType(), exits2);
        this.gridContainer.setCellTypeAndExits(
          x,
          y + 1,
          cell1.getType(),
          exits1
        );
      }
    }

    cellGroup.node.destroy();

    this.checkPathValidity();
  }

  // 网格坐标转世界坐标
  private gridToWorld(gridX: number, gridY: number): Vec3 {
    return this.gridContainer.gridToWorld(gridX, gridY);
  }

  public isAnyCellGroupPickedUp(): boolean {
    return this.cellGroupContainer.isAnyCellGroupPickedUp();
  }

  public setPickedCellGroup(cellGroup: CellGroup | null) {
    this.cellGroupContainer.setPickedCellGroup(cellGroup);
  }

  public rotatePickedCellGroup(): void {
    this.cellGroupContainer.rotatePickedCellGroup();
  }

  public getPickedCellGroup(): CellGroup | null {
    return this.cellGroupContainer.getPickedCellGroup();
  }

  public checkPathValidity(): boolean {
    const isValid = this.gridContainer.validatePath();
    if (isValid) {
      this.showSuccessPanel();
    }
    return isValid;
  }

  // 显示成功面板
  showSuccessPanel() {
    if (this.successPanel && !this.successPanelInstance) {
      this.successPanelInstance = instantiate(this.successPanel);
      const canvas = find('Canvas');
      if (canvas) {
        canvas.addChild(this.successPanelInstance);
      }
    }
  }

  // 隐藏成功面板
  hideSuccessPanel() {
    if (this.successPanelInstance) {
      this.successPanelInstance.destroy();
      this.successPanelInstance = null;
    }
  }

  startNewGame() {
    this.hideHomePanel();
    this.currentLevel = 0;
    this.saveLastLevel();
    this.restartLevel();
  }

  continueGame() {
    this.hideHomePanel();
    this.currentLevel = this.getLastLevel();
    this.restartLevel();
  }

  showLevelSelection() {
    if (this.selectLevelPanel && !this.selectLevelPanelInstance) {
        this.selectLevelPanelInstance = instantiate(this.selectLevelPanel);
        const canvas = find('Canvas');
        if (canvas) {
            canvas.addChild(this.selectLevelPanelInstance);
        }
    }
  }

  hideLevelSelection() {
    if (this.selectLevelPanelInstance) {
        this.selectLevelPanelInstance.destroy();
        this.selectLevelPanelInstance = null;
    }
  }

  showSettings() {
    // 显示设置界面
    console.log('显示设置');
    // TODO: 实现显示设置界面的逻辑
  }

  hideHomePanel() {
    if (this.homePanelInstance) {
        this.homePanelInstance.destroy();
        this.homePanelInstance = null;
    }
  }

  // 保存最后游玩的关卡
  private saveLastLevel() {
    localStorage.setItem(GameManager.LAST_LEVEL_KEY, this.currentLevel.toString());
  }

  // 获取最后游玩的关卡
  private getLastLevel(): number {
    const savedLevel = localStorage.getItem(GameManager.LAST_LEVEL_KEY);
    return savedLevel ? parseInt(savedLevel) : 0;
  }

  // 显示主界面
  private showHomePanel() {
    if (this.homePanel && !this.homePanelInstance) {
      this.homePanelInstance = instantiate(this.homePanel);
      const canvas = find('Canvas');
      if (canvas) {
        canvas.addChild(this.homePanelInstance);
      }
    }
  }
}
